Implicit Conversions
Promotions
-
Integer:
-
bool -> int
-
char -> int
-
char -> unsigned int
-
signed char -> int
-
unsigned char -> int
-
unsigned char -> unsigned int
-
short -> int
-
unsigned short -> int
-
unsigned short -> unsigned int
-
Unscoped enums -> int
-
Unscoped enums -> unsigned int
-
-
Floating-Point:
-
float -> double
-
Conversions
-
Integer:
-
int -> unsigned int
-
int -> long
-
int -> float
-
long -> short
-
unsigned int -> int
-
enum -> integer type
-
-
Floating-Point:
-
float -> int
-
float -> double
-
double -> int
-
double -> float
-
double -> long double
-
long double -> float
-
-
Boolean:
-
Any arithmetic type -> bool
-
Pointer -> bool
-
nullptr -> false, others -> true
-
-
-
Pointer:
-
nullptr -> any pointer type
-
0 -> pointer (legacy null pointer constant)
-
T* -> void*
-
Derived* -> Base*
-
-
Array:
-
T[N] -> T*
-
-
Function:
-
void f() → void (*)()
-
-
Qualification:
-
T* -> const T*
-
T& -> const T&
-
Casting
C Style
T value = (T)expression;
T value = T(expression);
-
No clear indication of intent.
-
Attempts multiple conversions in this order:
-
const_cast -
static_cast -
static_cast+const_cast -
reinterpret_cast -
reinterpret_cast+const_cast
-
-
Generally discouraged in modern C++ because it hides what kind of conversion is occurring.
-
Can silently perform dangerous conversions.
static_cast
-
Compile-time cast.
T value = static_cast<T>(expression);
double d = 3.14;
int i = static_cast<int>(d);
dynamic_cast
Derived* d = dynamic_cast<Derived*>(basePtr);
-
Runtime-checked cast.
-
Requires:
-
At least one virtual function in the base class
-
RTTI enabled
-
-
If casting pointers:
-
Returns nullptr on failure
-
-
If casting references:
-
Throws
std::bad_caston failure
-
class Base {
public:
virtual ~Base() {}
};
class Derived : public Base {};
Base* b = new Derived();
Derived* d = dynamic_cast<Derived*>(b); // Safe
const_cast
int* p = const_cast<int*>(constPtr);
-
Used only to add or remove
constorvolatile.
void func(const int* p) {
int* modifiable = const_cast<int*>(p);
}
-
Removing const is only safe if the original object was not actually declared const.
-
Modifying a truly const object is undefined behavior.
-
Cannot:
-
Change type
-
Change memory layout
-
Perform numeric conversions
-
reinterpret_cast
-
Low-level, bitwise reinterpretation.
T value = reinterpret_cast<T>(expression);
-
Used for:
-
Converting between unrelated pointer types
-
Pointer ↔ integer conversions
-
Interpreting raw memory
-
int x = 65;
char* p = reinterpret_cast<char*>(&x);
-
Characteristics:
-
No safety guarantees
-
No runtime checks
-
Highly platform-dependent behavior possible
-
-
Used primarily in:
-
Systems programming
-
Serialization
-
Memory manipulation
-
std::bit_cast (C++20)
-
Safer alternative to
reinterpret_castfor value reinterpretation. -
It enforces strict compile-time guarantees and avoids undefined behavior related to type aliasing and object lifetime.
#include <bit>
float f = 1.0f;
uint32_t bits = std::bit_cast<uint32_t>(f);
-
Performs safe bitwise copy between same-sized types.
Type Of
-
typeidallows to check the type of an expression.
typeid (expression)
-
This operator returns a reference to a constant object of type
type_infothat is defined in the standard header<typeinfo>. -
A value returned by
typeidcan be compared with another value returned by typeid using operators==and!=or can serve to obtain a null-terminated character sequence representing the data type or class name by using its name() member. -
The string returned by member name of type_info depends on the specific implementation of your compiler and library. It is not necessarily a simple string with its typical type name, like in the compiler used to produce this output.
#include <iostream>
#include <typeinfo>
using namespace std;
int main () {
int* a,b;
a = 0; b = 0;
if (typeid(a) != typeid(b)) {
std::cout << "a and b are of different types:\n";
std::cout << "a is: " << typeid(a).name() << '\n';
std::cout << "b is: " << typeid(b).name() << '\n';
}
return 0;
}
-
When typeid is applied to classes, typeid uses the RTTI to keep track of the type of dynamic objects. When typeid is applied to an expression whose type is a polymorphic class, the result is the type of the most derived complete object.
Size Of
x = sizeof (char);
-
The value returned by sizeof is a compile-time constant, so it is always determined before program execution.
Aliasing
-
Syntax:
-
In C and C++:
typedef existing_type new_type_name; -
In C++:
using new_type_name = existing_type; -
Both aliases defined with
typedefand aliases defined withusingare semantically equivalent. -
The only difference being that
typedefhas certain limitations in the realm of templates thatusinghas not. -
Neither
typedefnorusingcreate new distinct data types. They only create synonyms of existing types.
-